home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Visual Database / Visual Foxpro 6.0 (Ent. Edition) / Vf6ent Extractor.EXE / TOOLS / XSOURCE / XSOURCE.ZIP / vfpsource / wizards / Wztable / wzdbceng.prg < prev    next >
Encoding:
Text File  |  1998-05-01  |  16.7 KB  |  538 lines

  1. *- DBC wizard engine
  2.  
  3. #INCLUDE wzdbc.h
  4. #define d_KEY_CHILDTAG        13    && For RELATION objects: name of child (from) index tag ascii char
  5. #define d_KEY_RELTABLE        18    && For RELATION objects: name of related table  ascii char
  6. #define d_KEY_RELTAG        19    && For RELATION objects: name of related index tag  ascii char
  7.  
  8. DEFINE CLASS DBCEngine AS WizEngineAll
  9.  
  10.     lInitValue = .t.
  11.     iHelpContextID = 1895825424
  12.     lPopulate = .F.                && populate tables with sample data - set on Finish page of Wizard
  13.     iModify = 1                    && 2 = modify after done
  14.  
  15.     PROCEDURE ProcessOutput
  16.         *- this is where the real work is done
  17.  
  18.         PRIVATE cRIInfo,cParTable,cParTag,cChiTable,cChiTag
  19.         
  20.         LOCAL lnStart,lnSize,lcKey,lcValue,lnRec,lnObjID
  21.         LOCAL cOldSafety, cNewPath, cThisfld, cTagname, iMaxKeyLen, iCurTable, cTableName, cTablePath
  22.         LOCAL cTableFriendlyName, lHaveRels, i, j, k, cOldDatabase, iDBCCount, iRelsCount
  23.         LOCAL cKey, cRefTable, cRefPrimaryKey, cNewTableRef, cShortname, iMaxFields
  24.         LOCAL cNewTagName,lcNewDBCStem,lcOldDBCStem,lnViewCount
  25.         LOCAL lcOldSQL,lcNewSQL,lcViewName
  26.  
  27.         LOCAL ARRAY aContents[1]
  28.         LOCAL ARRAY aViews[1]
  29.         LOCAL ARRAY aOpenDBCs[1,2]
  30.         LOCAL ARRAY aStru[1,1]
  31.         LOCAL ARRAY aNewFields[1,1]
  32.         LOCAL ARRAY aTempFlds[1,1]
  33.  
  34.         *- create new database
  35.         cOldSafety = SET("SAFETY")
  36.         
  37.         SET SAFETY ON
  38.         THIS.cOutFile = PUTFILE(C_DESTDBC_LOC, THIS.JustFName(oWizard.cTemplateDBC), "DBC")
  39.  
  40.         IF EMPTY(THIS.cOutFile)
  41.             RETURN .F.
  42.         ENDIF
  43.  
  44.         IF LOWER(THIS.cOutFile) == LOWER(oWizard.cTemplateDBC)
  45.             THIS.Alert(E_SAMEDBC_LOC)
  46.             RETURN .F.
  47.         ENDIF
  48.         
  49.         WAIT WINDOW C_BUSYDBC_LOC NOWAIT
  50.         
  51.         SET SAFETY OFF
  52.  
  53.         *- make sure the DBC isn't already open somehow
  54.         cOldDatabase = SET("DATABASE")
  55.         iDBCCount = ADATABASES(aOpenDBCs)
  56.         FOR i = 1 TO iDBCCount
  57.             IF LOWER(aOpenDBCs[i,2]) = LOWER(THIS.cOutFile)
  58.                 SET DATABASE TO (THIS.cOutFile)
  59.                 CLOSE DATABASE
  60.                 EXIT
  61.             ENDIF
  62.         NEXT
  63.  
  64.         *- and make sure it's not open as a table either
  65.         iDBCCount = AUSED(aOpenDBCs)
  66.         FOR i = 1 TO iDBCCount
  67.             IF DBF(aOpenDBCs[i,1]) = UPPER(THIS.cOutFile)
  68.                 USE IN (aOpenDBCs[i,1])
  69.                 EXIT
  70.             ENDIF
  71.         NEXT
  72.                 
  73.         CREATE DATABASE (THIS.cOutFile)
  74.         IF !FILE(THIS.cOutFile)
  75.             *- error -- failed to create the database
  76.             THIS.Alert(E_CREATEDBCERR_LOC)
  77.             RETURN .F.
  78.         ENDIF
  79.         
  80.         WAIT WINDOW C_BUSYSTR_LOC NOWAIT
  81.         
  82.         SET DATABASE TO (THIS.cOutFile)
  83.         CLOSE DATABASE
  84.         
  85.         cNewPath = oEngine.AddBS(THIS.JustPath(oEngine.cOutFile))
  86.         
  87.         *- open new DBC
  88.         IF USED("_newDBC")
  89.             USE IN _newDBC
  90.         ENDIF
  91.         SELECT 0
  92.         USE (THIS.cOutFile) ALIAS _newDBC
  93.         IF !USED()
  94.             THIS.Alert(E_OPENDBCERR_LOC)
  95.             RETURN .F.
  96.         ENDIF
  97.         ZAP
  98.         PACK
  99.  
  100.         IF !USED("_templateDBC")
  101.             SELECT 0
  102.             USE (oWizard.cTemplateDBC) SHARED AGAIN ALIAS _templateDBC
  103.             IF !USED()
  104.                 THIS.Alert(E_OPENDBCTEMPERR_LOC)
  105.                 RETURN .F.
  106.             ENDIF
  107.         ENDIF
  108.         
  109.         SELECT _templateDBC
  110.         SCAN FOR ALLTRIM(objecttype) = "Database" AND !DELETED()
  111.             SCATTER MEMO TO aContents
  112.             INSERT INTO _newDBC FROM ARRAY aContents
  113.         ENDSCAN
  114.         
  115.         *- add views
  116.         WAIT WINDOW C_BUSYVUE_LOC NOWAIT
  117.  
  118.         SELECT crsTables
  119.         SCAN FOR lInclude AND LOWER(ALLT(crsTables.objectType)) == "view"
  120.             SELECT _templateDBC
  121.             LOCATE FOR TRIM(objectType) == "View" AND LOWER(TRIM(objectName)) == LOWER(TRIM(crsTables.objectName))
  122.             IF !FOUND()
  123.                 LOOP
  124.             ENDIF
  125.             
  126.             iParentID = _templateDBC.objectID
  127.             
  128.             INSERT INTO _newDBC ;
  129.                 VALUES (;
  130.                     RECNO("_newDBC") + 1, ;
  131.                     1, ;
  132.                     _templateDBC.objectType, ;
  133.                     _templateDBC.objectName, ;
  134.                     _templateDBC.property, ;
  135.                     _templateDBC.code, ;
  136.                     _templateDBC.riinfo, ;
  137.                     _templateDBC.user)
  138.             
  139.             iNewParentID = _newDBC.objectID
  140.             
  141.             *- now do fields
  142.             SELECT * FROM _templateDBC ;
  143.                 WHERE LOWER(TRIM(_templateDBC.objectType)) = "field"  AND ;
  144.                     _templateDBC.parentID = m.iParentID ;
  145.                 INTO ARRAY aContents
  146.                 
  147.             *- update parentID for these records
  148.             FOR i = 1 TO ALEN(aContents,1)
  149.                 aContents[i, 2] = iNewParentID
  150.                 aContents[i, 1] = iNewParentID + i
  151.             NEXT
  152.             
  153.             INSERT INTO _newDBC FROM ARRAY aContents
  154.  
  155.             SELECT crsTables
  156.             
  157.         ENDSCAN        && doing views
  158.         
  159.         USE IN _newDBC
  160.  
  161.         WAIT WINDOW C_BUSYDBF_LOC NOWAIT
  162.         
  163.         OPEN DATABASE (THIS.cOutFile)
  164.         SET DATABASE TO (THIS.cOutFile)
  165.         SELECT crsTables
  166.         this.HadError = .f.
  167.         this.SetErrorOff = .t.
  168.  
  169.         SCAN FOR lInclude AND LOWER(ALLT(crsTables.objectType)) == "table"
  170.             IF USED("_oldDBF")
  171.                 USE IN _oldDBF
  172.             ENDIF
  173.             SELECT 0
  174.             USE (TRIM(crsTables.tablePath)) AGAIN SHARED ALIAS _oldDBF
  175.             AFIELDS(aStru)
  176.             cName = ALLTRIM(crsTables.objectName)
  177.             cTablePath = m.cNewpath + ALLT(crsTables.tableName)
  178.             IF FILE(m.cTablePath)
  179.                 ERASE (m.cTablePath)
  180.             ENDIF
  181.             IF THIS.HadError                    
  182.                 EXIT
  183.             ENDIF
  184.                 
  185.             CREATE TABLE (m.cNewpath + ALLT(crsTables.tableName)) ;
  186.                 NAME "&cName" ;
  187.                 FROM ARRAY aStru
  188.                                     
  189.             USE IN _oldDBF
  190.             
  191.             IF THIS.HadError
  192.                 EXIT
  193.             ENDIF
  194.             
  195.             IF THIS.lPopulate
  196.                 APPEND FROM (TRIM(crsTables.tablePath))
  197.             ENDIF
  198.             
  199.             USE
  200.  
  201.             cNewTableRef = STRTRAN(ALLT(crsTables.objectName)," ","_")
  202.  
  203.             *- THIS.SetErrorOff = .F.
  204.             *- set captions, masks and format
  205.             *- CREATE CURSOR crsFields (tablename C(128), fname C(128), fieldname C(50), ftype C(1), flen N(3,0), ;
  206.             *-        fdec N(2,0), fnull L, makeTag L, fpos N(3,0), lnocptrans L, fmask C(128), fformat C(2), tagname C(10), comment c(254))
  207.             SELECT * FROM crsFields ;
  208.                 WHERE LOWER(ALLTRIM(tablename)) == LOWER(ALLTRIM(crsTables.tablename));
  209.                 INTO ARRAY aTempFlds
  210.                 
  211.             FOR i = 1 TO ALEN(aTempFlds,1)
  212.                 IF !EMPTY(aTempFlds[i,3])
  213.                     DBSETPROP(cNewTableRef + "." + ALLTRIM(aTempFlds[i,2]),"FIELD","CAPTION",ALLTRIM(aTempFlds[i,3]))
  214.                 ENDIF
  215.                 IF !EMPTY(aTempFlds[i,11])
  216.                     DBSETPROP(cNewTableRef + "." + ALLTRIM(aTempFlds[i,2]),"FIELD","INPUTMASK",ALLTRIM(aTempFlds[i,11]))
  217.                 ENDIF
  218.                 IF !EMPTY(aTempFlds[i,12])
  219.                     DBSETPROP(cNewTableRef + "." + ALLTRIM(aTempFlds[i,2]),"FIELD","FORMAT",ALLTRIM(aTempFlds[i,12]))
  220.                 ENDIF
  221.                 IF !EMPTY(aTempFlds[i,14])
  222.                     DBSETPROP(cNewTableRef + "." + ALLTRIM(aTempFlds[i,2]),"FIELD","COMMENT",ALLTRIM(aTempFlds[i,14]))
  223.                 ENDIF
  224.                 NEXT
  225.         ENDSCAN
  226.         
  227.         IF THIS.HadError
  228.             THIS.Alert(STRTRAN(E_CREATETBLERR_LOC,"@1",m.cTablePath))
  229.             THIS.HadError = .F.
  230.             RETURN .F.
  231.         ENDIF
  232.         
  233.         *- build indexes and update DBC captions
  234.  
  235. *-    CURSOR crsTables (lInclude L, objectname C(128), objecttype C(10), ;
  236. *-    tablename C(128), tablepath M, objectid I, parentid I, property M, code M, ;
  237. *-    riinfo C(6), user M)
  238.  
  239. *-     CURSOR crsFields (tablename C(128), fname C(128), fieldname C(50), ftype C(1), flen N(3,0), ;
  240. *-    fdec N(2,0), fnull L, makeTag L, fpos N(3,0), lnocptrans L, fmask C(128), fformat C(2))
  241.  
  242.         WAIT WINDOW C_BUSYIDX_LOC NOWAIT
  243.         SELECT crsTables
  244.         *- iCurTable = 1
  245.         *- pass #1 -- indexes
  246.         SCAN FOR crsTables.lInclude AND LOWER(ALLT(crsTables.objectType)) == "table"
  247.             iCurTable = RECNO()
  248.             cTableName = ALLT(crsTables.tablename)
  249.             cShortName = ALLT(crsTables.objectName)
  250.             cNewTableRef = STRTRAN(ALLT(crsTables.objectName)," ","_")
  251.             IF USED("_newTable")
  252.                 USE IN _newTable
  253.             ENDIF
  254.             USE (m.cNewpath + ALLT(crsTables.tableName)) ALIAS _newTable IN 0
  255.             
  256.             SELECT * FROM crsFields ;
  257.                 WHERE LOWER(ALLTRIM(crsFields.tablename)) == LOWER(ALLTRIM(crsTables.tablename)) ;
  258.                 INTO ARRAY aNewFields
  259.             iMaxFields = _TALLY
  260.             
  261.             FOR k = 1 TO iMaxFields
  262.                 m.cThisfld = ALLTRIM(aNewFields[k,2])
  263.                 m.cTagname = IIF(EMPTY(aNewFields[k,13]),m.cThisFld,ALLTRIM(aNewFields[k,13]))
  264.                 m.cTagname = IIF(LEN(m.cTagname) > 10, LEFT(m.cTagname,10), m.cTagname)
  265.                 IF aNewFields[k,8]
  266.                       m.iMaxKeyLen = IIF(SET("collate") == "MACHINE",240,120) - IIF(aNewFields[k,7],1,0)
  267.                       IF aNewFields[k,4] = "C" AND aNewFields[k,5] > m.iMaxKeyLen
  268.                           cIndexExpr = "LEFT(" + m.cThisfld + "," + ALLTRIM(STR(m.iMaxKeyLen)) + ")"
  269.                       ELSE
  270.                         cIndexExpr = m.cThisfld
  271.                     ENDIF
  272.                     DO CASE
  273.                     CASE LOWER(ALLT(aNewFields[k,2]))=LOWER(oWizard.aKeyfield[iCurTable])
  274.                           ALTER TABLE _newtable ADD PRIMARY KEY &cIndexExpr TAG &cTagname
  275.                     CASE aNewFields[k,15]
  276.                           ALTER TABLE _newtable ADD UNIQUE &cIndexExpr TAG &cTagname
  277.                       OTHERWISE
  278.                         *- create the index the old way
  279.                         SELECT _newTable
  280.                         INDEX ON &cIndexExpr TAG &cTagname
  281.                     ENDCASE
  282.                 ENDIF
  283.             NEXT
  284.         ENDSCAN
  285.         
  286. *- col 1: description that shows in combobox
  287. *- col 2: name of other table in DBC 
  288. *- col 3: type of relation (1 = none; 2 = 1-many; 3 = many-1
  289. *- col 4: field in other table
  290. *- col 5: tag in linked-to table
  291. *- col 6: key expression in linked to table
  292. *- col 7: possible new key field to add
  293. *- col 8: this table
  294. *- col 9: record #
  295. *- col 10: active? (L -- if table is removed, set to .F. and don't show)
  296. *- col 11: name of tag in this (parent) table
  297. *- CREATE CURSOR crsRels (cDesc C(200), cRelTable C(128), iType I, cRelField C(128), cTag C(10), ;
  298. *-    cKey C(240), cNewKey C(128), cTable C(128), irec I, lActive L, cThisTag C(10))
  299.         *- pass #2 -- relations
  300.         SCAN FOR crsTables.lInclude AND LOWER(ALLT(crsTables.objectType)) == "table"
  301.             iCurTable = RECNO()
  302.             cTableName = ALLT(crsTables.tablename)
  303.             cShortName = ALLT(crsTables.objectName)
  304.             cNewTableRef = STRTRAN(ALLT(crsTables.objectName)," ","_")
  305.             IF USED("_newTable")
  306.                 USE IN _newTable
  307.             ENDIF
  308.             USE (m.cNewpath + ALLT(crsTables.tableName)) ALIAS _newTable IN 0
  309.  
  310.             SELECT * FROM crsRels ;
  311.                 WHERE LOWER(TRIM(crsRels.ctable)) == LOWER(TRIM(crsTables.objectname)) AND crsRels.iType > 1 AND crsRels.lActive ;
  312.                 INTO ARRAY wzat_rels
  313.             iRelsCount = _TALLY
  314.  
  315.             SELECT * FROM crsFields ;
  316.                 WHERE LOWER(ALLTRIM(crsFields.tablename)) == LOWER(ALLTRIM(crsTables.tablename)) ;
  317.                 INTO ARRAY aNewFields
  318.             iMaxFields = _TALLY
  319.                         
  320.             FOR k = 1 TO iMaxFields
  321.                 m.cThisfld = ALLTRIM(aNewFields[k,2])
  322.                 m.cTagname = IIF(EMPTY(aNewFields[k,13]),m.cThisFld,ALLTRIM(aNewFields[k,13]))
  323.                 m.cTagname = IIF(LEN(m.cTagname) > 10, LEFT(m.cTagname,10), m.cTagname)
  324.  
  325.                 IF m.iRelsCount > 0
  326.                     FOR m.i = 1 TO iRelsCount
  327.                         DO CASE
  328.                             CASE wzat_rels[m.i, 3] = 2
  329.                                 *- need to create a 1-many link on this field from primary key
  330.                                 *- of link-to table
  331.                                 *- can either be primary or candidate key
  332.                                 IF LOWER(m.cThisfld)=LOWER(oWizard.aKeyfield[iCurTable]) OR;
  333.                                     aNewFields[k,15] AND LOWER(m.cThisfld)=LOWER(wzat_rels[m.i,11])
  334.                                     IF USED("_child")
  335.                                         USE IN _child
  336.                                     ENDIF
  337.                                     cTagname = IIF(!EMPTY(ALLTRIM(wzat_rels[m.i,11])),"TAG " + ALLTRIM(wzat_rels[m.i,11]),"")
  338.                                     cRefTable = m.cNewPath + JustFName(wzat_rels[m.i, 2])
  339.                                     USE (cRefTable) ALIAS _child IN 0 AGAIN
  340.                                     cOtherField = ALLT(wzat_rels[m.i,4])
  341.                                     cNewTagName = IIF(!EMPTY(ALLT(wzat_rels[m.i,5])),wzat_rels[m.i,5],cOtherField)
  342.                                     cNewTagName = LOWER(LEFT(ALLT(cNewTagName),10))
  343.                                     ALTER TABLE _child ;
  344.                                         ADD FOREIGN KEY &cOtherField  ;
  345.                                         TAG &cNewTagName ;
  346.                                         REFERENCES &cNewTableRef ;
  347.                                         &cTagname
  348.                                     USE IN _child
  349.                                 ENDIF
  350.                             CASE wzat_rels[m.i, 3] = 3
  351.                                 *- need to create a many-1 link on this field from primary key
  352.                                 *- of link-to table
  353.                                 IF LOWER(wzat_rels[m.i,5]) == LOWER(cTagname)
  354.                                     cRefTable = STRTRAN(THIS.JustStem(wzat_rels[m.i, 2])," ","_")
  355.                                     cKey = LOWER(ALLTRIM(aNewFields[k,2]))
  356.                                     cNewTagName = LEFT(m.cKey,10)
  357.                                     ALTER TABLE _newtable ;
  358.                                         ADD FOREIGN KEY &cKey ;
  359.                                         TAG &cNewTagName ;
  360.                                         REFERENCES &cRefTable;
  361.                                         TAG &cTagname
  362.                                 ENDIF
  363.                         ENDCASE
  364.                     NEXT
  365.                 ENDIF
  366.                 
  367.                 IF THIS.HadError
  368.                     EXIT
  369.                 ENDIF
  370.             NEXT    && going through fields
  371.             
  372.             *- see if user wants to add any new link fields
  373.             IF iRelsCount > 0
  374.                 FOR m.i = 1 TO iRelsCount
  375.                     IF wzat_rels[i,5] == C_NEWTAG_LOC AND !EMPTY(wzat_rels[i,7])
  376.                         *- user wants to add a new field to the child table
  377.                         IF USED("_child")
  378.                             USE IN _child
  379.                         ENDIF
  380.                         cTagname = wzat_rels[m.i,7]
  381.                         cRefTable = wzat_rels[m.i, 2]
  382.                         IF USED(cRefTable)
  383.                             USE IN (cRefTable)
  384.                         ENDIF
  385.                         USE (cRefTable) ALIAS _child IN 0
  386.                         DO CASE
  387.                             CASE wzat_rels[m.i, 3] == 2
  388.                                 *- other table is child
  389.                                 *- figure out the type and length of the new table primary key
  390.                                 j = oEngine.AColScan(@aNewField, oWizard.aKeyfield[iCurTable],1,.T.)
  391.                                 IF j == 0
  392.                                     *- error -- unable to locate the primary key
  393.                                     EXIT
  394.                                 ENDIF
  395.                                 m.cRefPrimaryKey = DBGETPROP(m.cShortname,"Table","PrimaryKey")
  396.                                 IF EMPTY(m.cRefPrimaryKey)
  397.                                     *- error -- unable to locate the primary key
  398.                                     EXIT
  399.                                 ENDIF
  400.                                 cKey = wzat_rels[m.i,7]
  401.                                 ALTER TABLE (m.cRefTable) ;
  402.                                     ADD FOREIGN KEY ;
  403.                                     TAG &cKey ;
  404.                                     REFERENCES &cNewTableRef ;
  405.                                     TAG &cRefPrimaryKey        
  406.                             CASE wzat_rels[m.i, 3] == 3
  407.                                 *- new table is child
  408.                                 *- figure out the type and length of the linking table primary key
  409.                                 m.cRefPrimaryKey = DBGETPROP(m.cRefTable,"Table","PrimaryKey")
  410.                                 IF EMPTY(m.cRefPrimaryKey)
  411.                                     *- error -- unable to locate the primary key
  412.                                     EXIT
  413.                                 ENDIF
  414.                                 DIMENSION aChild(1,1)
  415.                                 iAChildLen = AFIELDS(aChild,"_child")
  416.                                 j = THIS.AColScan(@aChild, UPPER(m.cRefPrimaryKey),1,.T.)
  417.                                 IF m.j == 0
  418.                                     *- error -- unable to locate the primary key
  419.                                     EXIT
  420.                                 ENDIF
  421.                                 cKey = wzat_rels[m.i,7]
  422.                                 ALTER TABLE (m.cTablename) ;
  423.                                     ADD FOREIGN KEY ;
  424.                                     TAG &cKey ;
  425.                                     REFERENCES &cRefTable;
  426.                                     TAG &cRefPrimaryKey
  427.  
  428.                         ENDCASE
  429.                         USE IN _child
  430.                     ENDIF
  431.                 NEXT
  432.             ENDIF
  433.  
  434.         ENDSCAN
  435.  
  436.         lcNewDBCStem = LOWER(JUSTSTEM(THIS.cOutfile))
  437.         lcOldDBCStem = LOWER(JUSTSTEM(oWizard.cTemplateDBC))
  438.         IF  !(lcNewDBCStem == lcOldDBCStem)
  439.             * Handle updating of local views
  440.             lnViewCount = aDBObject(aViews,"view")
  441.             FOR i = 1 TO lnViewCount
  442.                 IF DBGETPROP(aViews[m.i],'view','sourcetype')=1    &&local views
  443.                     lcOldSQL = DBGETPROP(aViews[m.i],'view','sql')
  444.                     IF ATC("!",lcOldSQL)#0  &&has old DBC references
  445.                         lcNewSQL = STRTRAN(lcOldSQL,lcOldDBCStem+"!","")
  446.                         lcViewName = aViews[m.i]
  447.                         CREATE SQL VIEW (lcViewName) AS &lcNewSQL.
  448.                     ENDIF
  449.                 ENDIF    
  450.             ENDFOR
  451.         ENDIF
  452.         
  453.         SET SAFETY &cOldSafety
  454.         
  455.         CLOSE DATABASE
  456.  
  457.         * Manually update any RI Rules if they exist
  458.  
  459.         CREATE CURSOR csrRIRULES (ParTable m,ChiTable m,ParTag m,ChiTag m,RIEXPR c(6))
  460.         SELECT _templateDBC
  461.         GO TOP
  462.         SCAN FOR ATC(ALLTRIM(objecttype),"Relation")#0 AND !DELETED() AND !EMPTY(ALLTRIM(riinfo))
  463.             STORE "" TO cParTable,cParTag,cChiTable,cChiTag,cRIInfo
  464.             THIS.GetRIInfo(@cParTable,@cParTag,@cChiTable,@cChiTag,@cRIInfo)
  465.             INSERT INTO csrRIRULES VALUES(cParTable,cChiTable,cParTag,cChiTag,cRIInfo)
  466.         ENDSCAN
  467.  
  468.         IF RECCOUNT("csrRIRULES") > 0 
  469.             SELECT 0
  470.             USE (THIS.cOutFile) ALIAS _newDBC
  471.             IF USED()
  472.                 SCAN FOR ATC(ALLTRIM(objecttype),"Relation")#0 AND !DELETED()
  473.                     STORE "" TO cParTable,cParTag,cChiTable,cChiTag,cRIInfo
  474.                     THIS.GetRIInfo(@cParTable,@cParTag,@cChiTable,@cChiTag,@cRIInfo)
  475.                     SELECT csrRIRULES
  476.                     LOCATE FOR UPPER(ALLTRIM(ParTable)) == UPPER(ALLTRIM(m.cParTable)) AND;
  477.                         UPPER(ALLTRIM(ChiTable)) == UPPER(ALLTRIM(m.cChiTable))
  478.                     IF FOUND() AND UPPER(ALLTRIM(ParTag)) == UPPER(ALLTRIM(m.cParTag)) AND;
  479.                         UPPER(ALLTRIM(ChiTag)) == UPPER(ALLTRIM(m.cChiTag))
  480.                         REPLACE _newDBC.riinfo WITH RIExpr
  481.                     ENDIF
  482.                     SELECT _newDBC
  483.                 ENDSCAN
  484.             ENDIF
  485.         ENDIF
  486.         USE
  487.         SET DATABASE TO (oWizard.cTemplateDBC)
  488.         CLOSE DATABASE
  489.         
  490.         WAIT CLEAR
  491.         
  492.         IF THIS.HadError
  493.             THIS.Alert(C_IDXERR_LOC)
  494.         ELSE
  495.             IF THIS.iModify = 2
  496.                 _SHELL = "MODIFY DATABASE [" + THIS.cOutFile + "]"
  497.             ENDIF
  498.         ENDIF
  499.         THIS.SetErrorOff = .F.
  500.         THIS.HadError = .F.
  501.  
  502.     ENDPROC
  503.  
  504.     PROCEDURE GetRIInfo
  505.         LPARAMETERS tcParTable, tcParTag, tcChiTable, tcChiTag, tcRIInfo
  506.         
  507.         LOCAL lnStart,lnSize,lcKey,lcValue,lnRec,lnObjID
  508.         tcRIInfo = ALLTRIM(riinfo)
  509.         lnObjID = parentid
  510.         lnStart=1
  511.         do while lnStart<=len(property)
  512.             lnSize=asc(substr(property,lnStart,1))+;
  513.                    (asc(substr(property,lnStart+1,1))*256)+;
  514.                    (asc(substr(property,lnStart+2,1))*256^2)+;
  515.                    (asc(substr(property,lnStart+3,1))*256^3)
  516.             lcKey=substr(property,lnStart+6,1)
  517.             lcValue=substr(property,lnStart+7,lnSize-8)
  518.             do case
  519.                case lcKey==chr(d_key_childtag)
  520.                  tcChiTag=lcValue
  521.                case lcKey==chr(d_key_reltable)
  522.                 IF LEFT(m.lcValue,1) = '"' 
  523.                     m.lcValue = SUBSTR(m.lcValue,2, LEN(m.lcvalue)-2)    && bytes, not chars
  524.                 ENDIF
  525.                  tcParTable=lcValue
  526.                case lcKey==chr(d_key_reltag)
  527.                  tcParTag=lcValue
  528.             endcase
  529.             lnStart=lnStart+lnSize
  530.         enddo
  531.         lnRec = RECNO()
  532.         LOCATE FOR objectid==lnObjID 
  533.         tcChiTable = ALLTRIM(objectname)
  534.         GO lnRec
  535.     ENDPROC
  536.  
  537. ENDDEFINE
  538.